﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Threading;
using System.Timers;
using intelliEssay.ApplicationExceptionReportingRecordingRedistributing;
using System.Xml.Serialization;
using System.Windows.Media.Animation;

namespace intelliEssayBugCheckSystem
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        object ImgLock = new object();
        bool detailVisible = true;
        currentGridDrawMethod cgdm = currentGridDrawMethod.b;
        public static Image klive;
        public static ListView bugList;
        static string[] months = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
        FileSystemWatcher fileSysWatcher;
        public MainWindow()
        {
            InitializeComponent();
            klive = KliveImage;
            bugList = BugList;
            ConnectionStatesImageSourceChange(ConnectionStatesImage, ApplicationStates.conState);
            // CreateGridView();
            System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged += new System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
            fileSysWatcher = new FileSystemWatcher(System.IO.Directory.GetCurrentDirectory(), "*.*");
            fileSysWatcher.Changed += new FileSystemEventHandler(fileSysWatcher_Changed);
            fileSysWatcher.Created += new FileSystemEventHandler(fileSysWatcher_Changed);
            fileSysWatcher.Deleted += new FileSystemEventHandler(fileSysWatcher_Changed);
            fileSysWatcher.Renamed += new RenamedEventHandler(fileSysWatcher_Renamed);
            fileSysWatcher.EnableRaisingEvents = true;
            fileSysWatcher.IncludeSubdirectories = true;
            //     BugList.Items.Add(new intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException(new ApplicationException()));
            //  BugCollection.LoadBugCollection();
            WelcomeBannerTextBlock.Text = "Hello, " + ApplicationStates.CurrentUserName;
            BugList.ItemsSource = intelliEssay.ApplicationExceptionReportingRecordingRedistributing.BugCollection.bugCollection;
            try
            {
                DrawGridStatistics(false);
            }
            catch { }
            GroupProgressTabItem.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(GroupProgressTabItem_PreviewMouseLeftButtonDown);
            ThreadPool.QueueUserWorkItem(o =>
                {
                    while (true)
                    {
                        AutomaticMechanism.DetectKingSoft();
                        //  CreateRestorationTimer();
                        Thread.Sleep(10000);
                    }
                });
        }

        void GroupProgressTabItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!detailVisible)
            {
                Storyboard sb = (Storyboard)Resources["OnLoaded2"];
                sb.Begin();
            }
        }

        private void DrawGridStatistics(bool mybug)
        {
            //calculating count of rectangles
            //     try
            //    {
            GC.Collect();
            DrawingSpace.Children.Clear();
            IEnumerable<intelliEssayException> local = LoadAllBugs();
            if (mybug)
                local = BugCollection.bugCollection;
            List<string> str = (from bug in local select bug.YearPlusMonth).Distinct<string>().ToList<string>();
            int[] corresSum = new int[str.Count];
            foreach (intelliEssayException o in local)
            {
                int idx = str.IndexOf(o.YearPlusMonth);
                if (idx >= 0)
                {
                    corresSum[idx]++;
                }
            }
            int maxNumber = corresSum.Max();
            StackPanel[] StackPanels = new StackPanel[str.Count];
            for (int i = 0; i < StackPanels.Length; i++)
            {
                StackPanels[i] = new StackPanel();
                StackPanels[i].Orientation = Orientation.Horizontal;
                Rectangle rect = new Rectangle();
                rect.Height = 30;
                rect.Width = ((DrawingSpace.Width - 150) / maxNumber) * corresSum[i];
                rect.Fill = Brushes.DarkGray;
                StackPanels[i].Children.Add(rect);
                StackPanels[i].Margin = new Thickness(10);
                TextBlock tb = new TextBlock() { Text = str[i] + " Count : " + corresSum[i].ToString() };
                StackPanels[i].Children.Add(tb);
                DrawingSpace.Children.Add(StackPanels[i]);
            }
            //     }
            // catch
            //    { }
            //sum up for each rectangles .

        }
        private void DrawGridStatisticsByUnsolved(bool mybug)
        {
            GC.Collect();
            DrawingSpace.Children.Clear();
            List<string> str;
            IEnumerable<intelliEssayException> local = LoadAllBugs().Where<intelliEssayException>(o => o.Status.ToLowerInvariant() != "resources\\done.png");
            if (mybug)
                local = BugCollection.bugCollection.Where<intelliEssayException>(o => o.Status.ToLowerInvariant() != "resources\\done.png");
            str = (from bug in local select bug.YearPlusMonth).Distinct<string>().ToList<string>();
            int[] corresSum = new int[str.Count];
            foreach (intelliEssayException o in local)
            {
                int idx = str.IndexOf(o.YearPlusMonth);
                if (idx >= 0)
                {
                    corresSum[idx]++;
                }
            }
            int maxNumber = corresSum.Max();
            StackPanel[] StackPanels = new StackPanel[str.Count];
            for (int i = 0; i < StackPanels.Length; i++)
            {
                StackPanels[i] = new StackPanel();
                StackPanels[i].Orientation = Orientation.Horizontal;
                Rectangle rect = new Rectangle();
                rect.Height = 30;
                rect.Width = ((DrawingSpace.Width - 150) / maxNumber) * corresSum[i];
                rect.Fill = Brushes.DarkGray;
                StackPanels[i].Children.Add(rect);
                StackPanels[i].Margin = new Thickness(10);
                TextBlock tb = new TextBlock() { Text = str[i] + " Count : " + corresSum[i].ToString() };
                StackPanels[i].Children.Add(tb);
                DrawingSpace.Children.Add(StackPanels[i]);
            }
        }
        private void DrawGridStatisticsByRatio(bool mybug)
        {
            GC.Collect();
            DrawingSpace.Children.Clear();
            IEnumerable<intelliEssayException> local = LoadAllBugs();
            if (mybug)
                local = BugCollection.bugCollection;
            List<string> str;
            str = (from bug in local select bug.YearPlusMonth).Distinct<string>().ToList<string>();
            double[] corresSum = new double[str.Count];
            for (int i = 0; i < str.Count; i++)
            {
                IEnumerable<intelliEssayException> ie1 = (from bug in local where bug.Status.ToLowerInvariant() != "resources\\done.png" && str[i] == bug.YearPlusMonth select bug);
                IEnumerable<intelliEssayException> ie2 = (from bug in local where bug.YearPlusMonth == str[i] select bug);
                corresSum[i] = ((double)ie2.Count() - (double)ie1.Count()) / (double)ie2.Count();
            }
            double maxNumber = corresSum.Max();
            StackPanel[] StackPanels = new StackPanel[str.Count];
            for (int i = 0; i < StackPanels.Length; i++)
            {
                StackPanels[i] = new StackPanel();
                StackPanels[i].Orientation = Orientation.Horizontal;
                Rectangle rect = new Rectangle();
                rect.Height = 30;
                rect.Width = ((DrawingSpace.Width - 150) / maxNumber) * corresSum[i];
                rect.Fill = Brushes.DarkGray;
                StackPanels[i].Children.Add(rect);
                StackPanels[i].Margin = new Thickness(10);
                TextBlock tb = new TextBlock() { Text = str[i] + " Count : " + corresSum[i].ToString() };
                StackPanels[i].Children.Add(tb);
                DrawingSpace.Children.Add(StackPanels[i]);
            }
        }

        void fileSysWatcher_Renamed(object sender, RenamedEventArgs e)
        {
            ConnectionStatesImage.Dispatcher.Invoke(new Action(() =>
            {
                if (CountOnlyMyBugsCheckBox.IsChecked.Value)
                {
                    bugList.ItemsSource = LoadAllBugs();
                    bugList.Items.Refresh();
                }
            }));
            /*    Monitor.Enter(CountOnlyMyBugsCheckBox);
                if (ApplicationStates.conState == ConnectionStates.Disconnected || ApplicationStates.conState == ConnectionStates.Syncing) return;
                ApplicationStates.conState = ConnectionStates.Syncing;
                Monitor.Exit(CountOnlyMyBugsCheckBox);
                ConnectionStatesImage.Dispatcher.Invoke(new Action(() =>
                {
                    ConnectionStatesImageSourceChange(ConnectionStatesImage, ConnectionStates.Syncing);
                }));
                CreateRestorationTimer();*/
        }

        private void CreateRestorationTimer()
        {
            /*System.Threading.TimerCallback tcb = new System.Threading.TimerCallback(o =>
            {
                if (ApplicationStates.conState == ConnectionStates.Disconnected) return;
                ApplicationStates.conState = ConnectionStates.Connected;
                ConnectionStatesImage.Dispatcher.Invoke(new Action(() =>
                {
                  Monitor.Enter(CountOnlyMyBugsCheckBox);
                    if (ApplicationStates.conState == ConnectionStates.Disconnected) return;
                    ConnectionStatesImageSourceChange(ConnectionStatesImage, ConnectionStates.Connected);
                  Monitor.Exit(CountOnlyMyBugsCheckBox);
                }));
            });
            System.Threading.Timer timer = new System.Threading.Timer(tcb, null, 2000, Timeout.Infinite);*/
        }

        void fileSysWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            ConnectionStatesImage.Dispatcher.Invoke(new Action(() =>
            {
                if (CountOnlyMyBugsCheckBox.IsChecked.Value)
                {
                    bugList.ItemsSource = LoadAllBugs();
                    bugList.Items.Refresh();
                }
            }));
            /*    Monitor.Enter(CountOnlyMyBugsCheckBox);
                if (ApplicationStates.conState == ConnectionStates.Disconnected || ApplicationStates.conState == ConnectionStates.Syncing) return;
                ApplicationStates.conState = ConnectionStates.Syncing;
                Monitor.Exit(CountOnlyMyBugsCheckBox);
             //   ConnectionStates cs = ApplicationStates.conState;
                ConnectionStatesImage.Dispatcher.Invoke(new Action(() =>
                {
                    ConnectionStatesImageSourceChange(ConnectionStatesImage,ConnectionStates.Syncing);
                }));
                CreateRestorationTimer();*/
        }
        public void NetworkChange_NetworkAvailabilityChanged(object sender, System.Net.NetworkInformation.NetworkAvailabilityEventArgs e)
        {
            //   Monitor.Enter(CountOnlyMyBugsCheckBox);
            ApplicationStates.conState = e.IsAvailable ? ConnectionStates.Connected : ConnectionStates.Disconnected;
            ConnectionStates cs = ApplicationStates.conState;
            ConnectionStatesImage.Dispatcher.BeginInvoke(new Action(() =>
            {
                ConnectionStatesImageSourceChange(ConnectionStatesImage, cs);

            }));
            //   Monitor.Exit(CountOnlyMyBugsCheckBox);
        }
        public static void KingSoftServiceImageSourceChange(bool serviceAvailable)
        {
            try
            {
                klive.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        try
                        {
                            BitmapImage bi = new BitmapImage();
                            bi.BeginInit();
                            string imgSource = serviceAvailable ? System.IO.Directory.GetCurrentDirectory() + "\\resources\\kingsoft.png" : System.IO.Directory.GetCurrentDirectory() + "\\resources\\kingsoftbroken.png";
                            klive.ToolTip = serviceAvailable ? "Kingsoft cloud disk is on - refresh in 60s" : "kingsoft cloud disk is off - refresh in 30s";
                            Uri uri = new Uri(imgSource);
                            bi.UriSource = uri;
                            bi.EndInit();
                            klive.Source = bi;
                            klive.Width = 32;
                            klive.Height = 32;
                        }
                        catch
                        { }
                    }));
            }
            catch { }
        }
        public void ConnectionStatesImageSourceChange(Image LogoImg, ConnectionStates conStates)
        {
            try
            {
                Monitor.Enter(ImgLock);
                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                string imgSource = System.IO.Directory.GetCurrentDirectory() + "\\";
                switch (conStates)
                {
                    case ConnectionStates.Connected:
                        {
                            imgSource += "X:\\intelliEssayBugCheck\\Bug Check System\\Resources\\cloud_check.png";
                            LogoImg.ToolTip = "Connected to Klive";
                            break;
                        }
                    case ConnectionStates.Disconnected:
                        {
                            imgSource += "X:\\intelliEssayBugCheck\\Bug Check System\\Resources\\cloud_delete.png";
                            LogoImg.ToolTip = "Unable to Connect to Klive";
                            break;
                        }
                    case ConnectionStates.Syncing:
                        {
                            imgSource += "X:\\intelliEssayBugCheck\\Bug Check System\\Resources\\cloud_backup.png";
                            LogoImg.ToolTip = "Syncing with Klive";
                            break;
                        }
                }
                Uri uri = new Uri(imgSource);
                bi.UriSource = uri;
                bi.EndInit();
                LogoImg.Source = bi;
                Monitor.Exit(ImgLock);
            }
            catch
            {
            }
        }

        private void LinkToAct_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start((((Hyperlink)sender).NavigateUri).ToString());
            }
            catch
            {
                MessageBox.Show("Cannot navigate to this site because this file is not available.", "Navigation Failure", MessageBoxButton.OK);
            }
        }
        private void RefreshBugList()
        {
            BugList.Items.Refresh();
        }
        private void MarkAsUndoneButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException iee = (intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException)BugList.SelectedItem;
                iee.Status = "Resources\\Pending.png";
                ApplicationStates.LockIO();
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.BugCollection.SaveBugCollection(DateTime.Now.ToString().Replace(" ", "").Replace("/", "").Replace(":", "") + ApplicationStates.CurrentUserName);
                ApplicationStates.ReleaseIO();
                RefreshBugList();
            }
            catch
            { }
        }

        private void MarkAsProcessingButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException iee = (intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException)BugList.SelectedItem;
                iee.Status = "Resources\\Processing.png";
                ApplicationStates.LockIO();
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.BugCollection.SaveBugCollection(DateTime.Now.ToString().Replace(" ", "").Replace("/", "").Replace(":", "") + ApplicationStates.CurrentUserName);
                ApplicationStates.ReleaseIO();
                RefreshBugList();
            }
            catch
            { }
        }

        private void MarkAsDoneButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException iee = (intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException)BugList.SelectedItem;
                iee.Status = "Resources\\Done.png";
                ApplicationStates.LockIO();
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.BugCollection.SaveBugCollection(DateTime.Now.ToString().Replace(" ", "").Replace("/", "").Replace(":", "") + ApplicationStates.CurrentUserName);
                ApplicationStates.ReleaseIO();
                RefreshBugList();
            }
            catch
            { }
        }

        private void RemoveBugItem_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException iee = (intelliEssay.ApplicationExceptionReportingRecordingRedistributing.intelliEssayException)BugList.SelectedItem;
                BugCollection.bugCollection.Remove(iee);
                ApplicationStates.LockIO();
                intelliEssay.ApplicationExceptionReportingRecordingRedistributing.BugCollection.SaveBugCollection(DateTime.Now.ToString().Replace(" ", "").Replace("/", "").Replace(":", "")+ApplicationStates.CurrentUserName);
                ApplicationStates.ReleaseIO();
                RefreshBugList();
            }
            catch
            { }
        }


        private void ShowOnlyMyBugsCheckBox_Clicked(object sender, RoutedEventArgs e)
        {
            try
            {
                if (ShowOnlyMyBugs.IsChecked.Value)
                {
                    BugList.ItemsSource = from bug in BugCollection.bugCollection select bug;
                    RefreshBugList();
                }
                else
                {
                    BugList.ItemsSource = LoadAllBugs();
                    RefreshBugList();
                }
            }
            catch
            {
                MessageBox.Show("File system is syncing files, try again a few moments later");
            }
        }
        public static List<intelliEssayException> LoadAllBugs()
        {
            ApplicationStates.LockIO();
            Stream stream;
            string[] users = new string[] { "罗量", "李希鹏", "宋小远", "镇明敏" };
            List<intelliEssayException> result = new List<intelliEssayException>();
            foreach (string user in users)
            {
                using (stream = File.Open("BugCollection" + user + ".xml", FileMode.Open))
                {
                    XmlSerializer xmlserializer = new XmlSerializer(typeof(List<intelliEssayException>));
                    List<intelliEssayException> other = (List<intelliEssayException>)xmlserializer.Deserialize(stream);
                    result.AddRange(other);
                }
            }
            return result;
        }

        private void OnlyUnsolvedCheckBox_Click(object sender, RoutedEventArgs e)
        {
            if (OnlyUnsolvedCheckBox.IsChecked.Value)
            {
                BugList.ItemsSource = from bug in BugCollection.bugCollection where bug.Status.ToLowerInvariant() != "resources\\done.png" select bug;
                RefreshBugList();
            }
            else
            {
                BugList.ItemsSource = BugCollection.bugCollection;
                RefreshBugList();
            }
        }

        private void MainWindows_Resized(object sender, SizeChangedEventArgs e)
        {
            // DrawGridStatistics();
        }

        private void DisplayMethod_SlectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (DisplayMethodComboBox.SelectedItem == DrawBySolvedComboBoxItem)
                {
                    if (CountOnlyMyBugsCheckBox.IsChecked.Value)
                    {
                        cgdm = currentGridDrawMethod.a;
                        DrawGridStatistics(true);
                    }
                    else
                    {
                        cgdm = currentGridDrawMethod.b;
                        DrawGridStatistics(false);
                    }
                }
                else if (DisplayMethodComboBox.SelectedItem == DrawByUnsolvedComboBoxItem)
                {
                    if (CountOnlyMyBugsCheckBox.IsChecked.Value)
                    {
                        cgdm = currentGridDrawMethod.c;
                        DrawGridStatisticsByUnsolved(true);
                    }
                    else
                    {
                        cgdm = currentGridDrawMethod.d;
                        DrawGridStatisticsByUnsolved(false);
                    }
                }
                else
                {
                    if (CountOnlyMyBugsCheckBox.IsChecked.Value)
                    {
                        cgdm = currentGridDrawMethod.e;
                        DrawGridStatisticsByRatio(true);
                    }
                    else
                    {
                        cgdm = currentGridDrawMethod.f;
                        DrawGridStatisticsByRatio(false);
                    }
                }
            }
            catch
            {
                MessageBox.Show("Try untick OnlyMyBug checkbox, data imcomplete");
            }
        }

        private void CountOnlyMyBugs_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                switch (cgdm)
                {
                    case currentGridDrawMethod.a:
                    case currentGridDrawMethod.b:
                        {
                            DrawGridStatistics(CountOnlyMyBugsCheckBox.IsChecked.Value);
                            break;
                        }
                    case currentGridDrawMethod.c:
                    case currentGridDrawMethod.d:
                        {
                            DrawGridStatisticsByUnsolved(CountOnlyMyBugsCheckBox.IsChecked.Value);
                            break;
                        }
                    case currentGridDrawMethod.e:
                    case currentGridDrawMethod.f:
                        {
                            DrawGridStatisticsByRatio(CountOnlyMyBugsCheckBox.IsChecked.Value);
                            break;
                        }
                }
            }
            catch
            {
                MessageBox.Show("Count My Bug(TM) is not available - data imcomplete");
                CountOnlyMyBugsCheckBox.IsChecked = false;
                CountOnlyMyBugsCheckBox.IsEnabled = false;
            }
        }

        private void BugList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                // intelliEssayException iee = (intelliEssayException)bugList.SelectedItem;
                if (!ShowOnlyMyBugs.IsChecked.Value)
                {
                    RemoveBugItem.Visibility = Visibility.Hidden;
                    MarkAsProcessingButton.Visibility = Visibility.Hidden;
                    MarkAsDoneButton.Visibility = Visibility.Hidden;
                    MarkAsUndoneButton.Visibility = Visibility.Hidden;
                }
                else
                {
                    RemoveBugItem.Visibility = Visibility.Visible;
                    MarkAsProcessingButton.Visibility = Visibility.Visible;
                    MarkAsDoneButton.Visibility = Visibility.Visible;
                    MarkAsUndoneButton.Visibility = Visibility.Visible;
                }
            }
            catch
            { }
        }

        private void ShowDetail_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                
                detailVisible = detailVisible ? false : true;
                intelliEssayException iee = (intelliEssayException)bugList.SelectedItem;
                StringBuilder stringb = new StringBuilder();
                if (bugList.SelectedItem == null)
                    stringb.Append("select an item to see its detail");
                stringb.Append("Message:"+ iee.Message+"\n");
                if (iee.StackTrace != null)
                    stringb.Append(iee.StackTrace);
                else
                    stringb.Append("This exception has no stack trace information");
                DetailPanel.Text = stringb.ToString();
            }
            catch { }
            if (!detailVisible)
            {
                Storyboard sb = (Storyboard)Resources["OnLoaded1"];
                sb.Begin();
            }
            else
            {
                Storyboard sb = (Storyboard)Resources["OnLoaded2"];
                sb.Begin();
            }

        }
    }
    enum currentGridDrawMethod
    {
        a, b, c, d, e, f
    }
}